package com.ydj.app.third.ai.yuanqi;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.google.gson.Gson;
import com.ydj.app.third.ai.ChatFluxListener;
import com.ydj.app.third.ai.deepseek.DeepseekChatStreamCompletionsRes;
import com.ydj.framework.exception.CommonException;
import com.ydj.framework.utils.BooleanValue;
import com.ydj.framework.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.scheduler.Schedulers;

import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Component
public class YuanQiManager {

    @Value("${tencent.yuanqi.token}")
    private String token;

    @Value("${tencent.yuanqi.assistantId}")
    private String assistantId;

    public String chatJson(List<YuanQiChatCompletionsReq.Message> messagesList, String userId) throws CommonException {
        YuanQiChatCompletionsRes dsRes = chat(messagesList, userId);
        if (dsRes == null) {
            CommonException.throwException("出现错误，请再试一次");
        }
        if (dsRes.getError() != null) {
            YuanQiChatCompletionsRes.ErrorBean errorBean = dsRes.getError();
            String msg = String.format("出现错误。错误码：%s。原因：%s", errorBean.getCode(), errorBean.getMessage());
            CommonException.throwException(msg);
        }
        if (dsRes.getChoices().isEmpty()) {
            CommonException.throwException("出现错误，模型返回缺失，请再试一次");
        }
        YuanQiChatCompletionsRes.Choices choicesBean = dsRes.getChoices().get(0);
        String content = choicesBean.getMessage().getContent();

        // 裁剪出html代码。正则找到 【```html】到【```】的一段内容。 如果不能提取，就整段保存好了
        String regex = "```json(.*?)```";
        Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            content = matcher.group(1).trim();
        }

        return content;
    }

    public YuanQiChatCompletionsRes chat(List<YuanQiChatCompletionsReq.Message> messagesList, String userId) {
        final String url = "https://yuanqi.tencent.com/openapi/v1/agent/chat/completions";
        try {
            YuanQiChatCompletionsReq req = new YuanQiChatCompletionsReq()
                    .setAssistant_id(assistantId)
                    .setUser_id(userId)
                    .setStream(false)
                    .setMessages(messagesList);

            String body = JsonUtils.toJson(req);
            long sendTs = System.currentTimeMillis();
            HttpResponse receiveRes = HttpRequest.post(url)
                    .header("X-Source", "openapi")
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + token)
                    .body(body)
                    .timeout(60 * 1000)
                    .setReadTimeout(0)
                    .execute();
            long costTime = System.currentTimeMillis() - sendTs;
            String receive = receiveRes.body();
            log.info("【元器发送对话】耗时{}, 返回{}", costTime, receive);

            YuanQiChatCompletionsRes res = new Gson().fromJson(receive, YuanQiChatCompletionsRes.class);
            return res;
        } catch (Exception e) {
            return null;
        }
    }

    public void chatFlux(List<YuanQiChatCompletionsReq.Message> messagesList, String userId, ChatFluxListener listener) {
        final String url = "https://yuanqi.tencent.com/openapi/v1/agent/chat/completions";
        YuanQiChatCompletionsReq req = new YuanQiChatCompletionsReq()
                .setAssistant_id(assistantId)
                .setUser_id(userId)
                .setStream(true)
                .setMessages(messagesList);
        String body = JsonUtils.toJson(req);

        //创建webclient客户端
        log.info("Chat 准备调用元器，userId={}, body={}", userId, body);
        WebClient webClient = WebClient.create(url);
        webClient.post()
                .uri(url)
                .header("X-Source", "openapi")
                .header("Content-Type", "application/json")
                .header("Authorization", "Bearer " + token)
                .bodyValue(body)
//                .accept(MediaType.TEXT_EVENT_STREAM)
                .retrieve()
                .bodyToFlux(String.class)
                .subscribeOn(Schedulers.boundedElastic())
                .doOnError(e -> {
                    log.error("Chat 异常:", e);
                    listener.error(e);
                })
                .subscribe(re -> {
                    log.info("Chat 收到消息:{}", re);
                    if ("[DONE]".equals(re)) {
                        listener.flux(re, true);
                        return;
                    }
                    YuanQiChatCompletionsRes res = JsonUtils.jsonToBean(re, YuanQiChatCompletionsRes.class);

                    YuanQiChatCompletionsRes.Delta deltaBean = Optional.ofNullable(res)
                            .map(YuanQiChatCompletionsRes::getChoices)
                            .map(choicesBeans -> choicesBeans.get(0))
                            .map(YuanQiChatCompletionsRes.Choices::getDelta)
                            .orElse(null);

                    if (deltaBean != null) {
                        if ("assistant".equals(deltaBean.getRole())) {
                            String content = "";
                            if (deltaBean.getContent() != null) {
                                content = deltaBean.getContent();
                            }
                            listener.flux(content, false);
                        }
                    }
                });
    }
}
